//
//  TwitterStatz.m
//  Statz
//
//  Created by dmaclach on 12/05/07.
//
// Copyright 2007 Nightfall Sofware
// 
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy
// of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
// License for the specific language governing permissions and limitations under
// the License.
//

#import "TwitterStatz.h"

#include <curl/easy.h>
#include <regex.h>
#import "StatusUpdate.h"

static NSLock *gPreferencesLock = nil;

static size_t TwitterWriteFunc( void *ptr, size_t size, size_t nmemb, void *stream) {
  return size*nmemb;
}

@implementation TwitterStatz
- (id)init {
  self = [super initWithNibNamed:@"TwitterPrefs"];
  if (self != nil) {
    curl_ = curl_easy_init();
    if (!curl_) {
      [self release];
      self = nil;
    }
    if (!gPreferencesLock) {
      gPreferencesLock = [[NSLock alloc] init];
    }    
  }
  return self;
}

- (NSString*)uuid {
  return @"C03A68C8-BBC8-49AB-8140-8EC1BFF6CB93";
}

- (NSString*)name {
  return @"Twitter";
}

- (NSString*)serverName {
  return @"www.twitter.com";
}

- (void)showAccountPreferences:(id)sender {
  [gPreferencesLock lock];
  [super showAccountPreferences:sender];
}

- (IBAction)closePreferences:(id)sender {
  [super closePreferences:sender];
  [gPreferencesLock unlock];
}

- (void)dealloc {
  if(curl_) {
    curl_easy_cleanup(curl_);
  }
  [oldValue_ release];
  [super dealloc];
}

- (NSImage *)image {
  NSString *path = [[NSBundle bundleForClass:[self class]] pathForImageResource:@"twitterIcon"];
  return path ? [[[NSImage alloc] initWithContentsOfFile:path] autorelease] : nil;
}


- (StatzUpdateValue)updateStatz:(StatusUpdate*)sender {
  StatzUpdateValue updatedValue = kStatzUpdateError;
  NSString *newValue = [sender status];
  if ([oldValue_ isEqualToString:newValue]) {
    return kStatzUpdateNotChanged;
  }
  if ([[self password] length] == 0 || [[self username] length] == 0) {
    [self performSelectorOnMainThread:@selector(showAccountPreferences:) withObject:nil waitUntilDone:YES];
    [gPreferencesLock lock];
    [gPreferencesLock unlock];
  }
  NSString *username = [self username];
  NSString *password = [self password];
  if ([username length] == 0 || [password length] == 0) return updatedValue;
  NSString *escapedValue = [newValue stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  NSString *message = [NSString stringWithFormat:@"status=%@", escapedValue];
  CURLcode code = CURLE_FAILED_INIT;
  curl_easy_reset(curl_);
  code = curl_easy_setopt(curl_, CURLOPT_URL, "http://twitter.com/statuses/update.xml");
  require_curl_noerr(code, curlFailed);
  code = curl_easy_setopt(curl_, CURLOPT_USERPWD, [[NSString stringWithFormat:@"%@:%@", username, password] UTF8String]);
  require_curl_noerr(code, curlFailed);
  code = curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, [message UTF8String]);
  require_curl_noerr(code, curlFailed);
  code = curl_easy_setopt(curl_, CURLOPT_VERBOSE, 0);
  require_curl_noerr(code, curlFailed);
  code = curl_easy_setopt(curl_, CURLOPT_NOPROGRESS, 1);
  require_curl_noerr(code, curlFailed);
  code = curl_easy_setopt(curl_, CURLOPT_POST, 1);
  require_curl_noerr(code, curlFailed);
  code = curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, TwitterWriteFunc);
  require_curl_noerr(code, curlFailed);
  code = curl_easy_setopt(curl_, CURLOPT_WRITEDATA, nil);
  require_curl_noerr(code, curlFailed);
  code = curl_easy_perform(curl_);
  require_curl_noerr(code, curlFailed);
  unsigned long response;
  code = curl_easy_getinfo(curl_, CURLINFO_RESPONSE_CODE, &response);
  require_curl_noerr(code, curlFailed);
  if (response != 200) {
    NSLog(@"Error %d from curl", response);
    goto curlFailed;
  }
  [oldValue_ autorelease];
  oldValue_ = [newValue copy];
  return kStatzUpdateSuccess;
curlFailed:
  return kStatzUpdateError;
}
@end
